package breaker

import (
	"context"
	"github.com/go-kratos/aegis/circuitbreaker"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	rand2 "math/rand"
	"time"
)

type InterceptorBreaker struct {
	breaker   circuitbreaker.CircuitBreaker
	threshold int
}

func NewInterceptorBreaker(breaker circuitbreaker.CircuitBreaker, threshold int) *InterceptorBreaker {
	return &InterceptorBreaker{breaker: breaker, threshold: threshold}
}

func (b *InterceptorBreaker) BuildServerInterceptor() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
		if b.breaker.Allow() == nil {
			resp, err := handler(ctx, req)
			s, _ := status.FromError(err)
			if s != nil && s.Code() == codes.Unavailable {
				b.breaker.MarkFailed()
			} else {
				b.breaker.MarkSuccess()
			}
			return resp, err
		} else {
			b.breaker.MarkFailed()
			return nil, status.Errorf(codes.Unavailable, "熔断")
		}

	}

}
func (b *InterceptorBreaker) BuildServerInterceptorV1() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
		if !b.allow() {
			b.threshold = 0
			time.AfterFunc(time.Minute, func() {
				b.threshold = 1
			})
		}
		rand := rand2.Intn(100)
		if rand <= b.threshold {
			resp, err = handler(ctx, req)
			if err == nil && b.threshold != 0 {
				// 调大threshold
			} else if b.threshold != 0 {
				// 调小threshold

			}
		}
		return nil, nil
	}
}
func (b *InterceptorBreaker) allow() bool {
	// 监控数据
	return true
}
